﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using Orchard.ContentManagement;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Mvc.Html;
using Orchard.Utility.Extensions;
using Orchard;

namespace Contrib.Projections.Providers.Layouts {
    public class LayoutShapes : IDependency {
        public LayoutShapes() {
            T = NullLocalizer.Instance;
        }

        public Localizer T { get; set; }

        [Shape]
        public void Split(dynamic Display, TextWriter Output, HtmlHelper Html, string Separator, IEnumerable<dynamic> Items) {
            if (Items == null)
                return;

            var items = Items.ToList();
            var itemsCount = items.Count;

            if (itemsCount < 1)
                return;

            Output.Write(String.Join(Separator, items.Select(i => Display(i)).ToArray()));
        }

        /// The old Table code is commented out and the module now uses So.CustomShapes as a dependency. 
        /// This way the So.CustomShapes can also be used without this module or projector dependencies
        /*
         [Shape]
         public void Table(
             dynamic Display,
             TextWriter Output,
             IEnumerable<dynamic> Items,
             string Id,
             IEnumerable<string> Classes,
             IEnumerable<string> ItemClasses,
             IEnumerable<string> ItemHeaders,
             IDictionary<string, string> Attributes,
             IDictionary<string, string> ItemAttributes) {

             if (Items == null)
                 return;

             var count = Items.Count();
             if (count < 1)
                 return;

             const string tableTagName = "table";
             const string theadTagName = "thead";
             const string tBodyTagName = "tbody";
             const string itemTagName = "tr";
             //const string cellTagName = "td";
             const string thTagName = "th";

             var tableTag = GetTagBuilder(tableTagName, Id, Classes, Attributes);
             Output.Write(tableTag.ToString(TagRenderMode.StartTag));

             WriteTableThead(Output, ItemHeaders, theadTagName, thTagName, itemTagName);
             WriteTableTbody(Output, Display, count, tBodyTagName, Items, itemTagName, ItemClasses, ItemAttributes);

             Output.Write(tableTag.ToString(TagRenderMode.EndTag));
         }      

         private void WriteTableThead(TextWriter Output, IEnumerable<string> ItemHeaders, string theadTagName, string thTagName, string itemTagName) {
             var theadTag = GetTagBuilder(theadTagName, "", null, null);
             Output.Write(theadTag.ToString(TagRenderMode.StartTag));

             var itemTag = GetTagBuilder(itemTagName, "", null, null);
             Output.Write(itemTag.ToString(TagRenderMode.StartTag));
             foreach (var itemHeader in ItemHeaders) {
                 var celTagForThead = GetTagBuilder(thTagName, "", null, null);
                 Output.Write(celTagForThead.ToString(TagRenderMode.StartTag));
                 Output.Write(itemHeader);
                 Output.Write(celTagForThead.ToString(TagRenderMode.EndTag));
             }
             Output.Write(itemTag.ToString(TagRenderMode.EndTag));
             Output.Write(theadTag.ToString(TagRenderMode.EndTag));
         }

         private void WriteTableTbody(TextWriter Output, dynamic Display, int count, string tBodyTagName, IEnumerable<dynamic> Items, string itemTagName, IEnumerable<string> ItemClasses, IDictionary<string, string> ItemAttributes) {
             var bodyTag = GetTagBuilder(tBodyTagName, "", null, null);
             Output.Write(bodyTag.ToString(TagRenderMode.StartTag));
             var index = 0;
             foreach (var item in Items) {
                 var itemTagForTbody = GetTagBuilder(itemTagName, null, ItemClasses, ItemAttributes);
                 if (index == 0)
                     itemTagForTbody.AddCssClass("first");
                 if (index == count - 1)
                     itemTagForTbody.AddCssClass("last");
                 Output.Write(itemTagForTbody.ToString(TagRenderMode.StartTag));

                 const string cellTagName = "td";
                 var cellTag = GetTagBuilder(cellTagName, "", null, null);
                 Output.Write(cellTag.ToString(TagRenderMode.StartTag));
                 Output.Write(Display(item));
                 Output.Write(cellTag.ToString(TagRenderMode.EndTag));
                 Output.Write(itemTagForTbody.ToString(TagRenderMode.EndTag));
                 ++index;
             }
             Output.Write(bodyTag.ToString(TagRenderMode.EndTag));
         }  
         */

        static TagBuilder GetTagBuilder(string tagName, string id, IEnumerable<string> classes, IDictionary<string, string> attributes) {
            var tagBuilder = new TagBuilder(tagName);
            tagBuilder.MergeAttributes(attributes, false);
            foreach (var cssClass in classes ?? Enumerable.Empty<string>())
                tagBuilder.AddCssClass(cssClass);
            if (!string.IsNullOrWhiteSpace(id))
                tagBuilder.GenerateId(id);
            return tagBuilder;
        }
    }
}
